package com.ybchen.core;

import com.ybchen.annotation.EnableMyFeignClients;
import com.ybchen.annotation.MyFeignClient;
import org.reflections.Reflections;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.beans.Introspector;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

public class MyFeignRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        // 1. 获取 @EnableMyFeignClients 注解的 basePackages 配置
        Map<String, Object> enableAttrs = metadata.getAnnotationAttributes(EnableMyFeignClients.class.getName());
        String[] basePackages = (String[]) enableAttrs.get("basePackages");
        if (basePackages == null || basePackages.length == 0) {
            // 如果没有配置包路径，默认使用启动类所在包
            String defaultPackage = metadata.getClassName().substring(0, metadata.getClassName().lastIndexOf('.'));
            basePackages = new String[]{defaultPackage};
        }

        // 2. 扫描指定包
        Set<Class<?>> candidateComponents = scanCandidateComponents(basePackages);
        for (Class<?> clz : candidateComponents) {
            registerMyFeignClient(clz, registry);
        }
    }

    private Set<Class<?>> scanCandidateComponents(String[] basePackages) {
        Set<Class<?>> components = new LinkedHashSet<>();
        for (String basePackage : basePackages) {
            Reflections reflections = new Reflections(basePackage);
            Set<Class<?>> clients = reflections.getTypesAnnotatedWith(MyFeignClient.class);
            components.addAll(clients);
        }
        return components;
    }

    private void registerMyFeignClient(Class<?> clientClass, BeanDefinitionRegistry registry) {
        try {
            // 获取接口上的 @MyFeignClient 注解
            MyFeignClient annotation = clientClass.getAnnotation(MyFeignClient.class);
            if (annotation == null) {
                System.out.println("未找到 @MyFeignClient 注解: " + clientClass.getName());
                return;
            }

            String name = annotation.name();
            if (name.isEmpty()) {
                // 如果 name 没有配置，默认使用类名首字母小写
                name = Introspector.decapitalize(clientClass.getSimpleName());
            }
            String url = annotation.url();

            // 创建代理对象
            Object proxy = new MyFeignProxyFactory(clientClass, url).createProxy();

            // 注册到 Spring 容器
            BeanDefinition proxyBeanDefinition = BeanDefinitionBuilder
                    .genericBeanDefinition((Class<Object>) clientClass, () -> proxy)
                    .setScope(BeanDefinition.SCOPE_SINGLETON)
                    .getBeanDefinition();

            registry.registerBeanDefinition(name, proxyBeanDefinition);

            System.out.println("【MyFeign】注册Feign客户端: " + name + " -> " + url);

        } catch (Exception e) {
            throw new RuntimeException("Failed to register MyFeign client: " + clientClass.getName(), e);
        }
    }

}